package main;

//Nikolas Wolfe
//4/13/09
//CIS 4930
//Game of Life 2

/* =============================================================================
* Implements a Generic Toroidal 2D Array
*/

public class ToroidalArray<T>
{
	private final T[] array;
	private final int xMax;
	private final int yMax;
	
	@SuppressWarnings("unchecked")
	public ToroidalArray( int WIDTH, int HEIGHT )
	{
		this.xMax = WIDTH;
		this.yMax = HEIGHT;
		this.array = (T[]) new Object[ xMax * yMax ];
	}
	
	/* =========================================================================
	 * Setter
	 */
	public final void set(int x, int y, T val)
	{
		array[ calculateIndex(x, y) ] = val;
	}
	
	/* =========================================================================
	 * Getter
	 */
	public final T get(int x, int y)
	{
		return array[ calculateIndex(x, y) ];
	}
	
	/* =========================================================================
	 * Index offsets and boundary conditions
	 */
	private final int calculateIndex(int x, int y)
	{
		x = correctXForToroidalProperty(x);
		y = correctYForToroidalProperty(y);
		return ((x*yMax) + y);
	}
	
	private final int correctXForToroidalProperty(int x)
	{
		if( x < 0 || x >= this.xMax )
		{
			x = Math.abs((this.xMax - Math.abs(x))) % xMax;
			return x;
		}
		else {
			return x;
		}
	}
	
	private final int correctYForToroidalProperty(int y)
	{
		if( y < 0 || y >= this.yMax )
		{
			y = Math.abs((this.yMax - Math.abs(y))) % yMax;
			return y;
		}
		else {
			return y;
		}
	}
	
	/* =========================================================================
	 * Information Accessors
	 */
	public final int getXMax()
	{
		return xMax;
	}
	
	public final int getYMax()
	{
		return yMax;
	}
	
	public final int size()
	{
		return array.length;
	}
}
